package org.oschina.api.user.follow.service;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.oschina.Config;
import org.oschina.Constants;
import org.oschina.Message;
import org.oschina.ResultUtil;
import org.oschina.api.BaseService;
import org.oschina.api.index.service.IndexService;
import org.oschina.api.manage.config.service.ConfigService;
import org.oschina.api.user.follow.dao.UserFollowDAO;
import org.oschina.api.user.follow.model.UserFollow;
import org.oschina.api.user.follow.vo.UserFollowVo;
import org.oschina.api.user.mail.UserMailType;
import org.oschina.api.user.mail.service.UserMailService;
import org.oschina.api.user.user.service.UserService;
import org.oschina.api.user.user.vo.UserVo;
import org.oschina.bean.Pager;
import org.oschina.bean.Result;
import org.oschina.security.annotation.Require;
import org.oschina.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserFollowService extends BaseService {

	@Autowired
	private UserFollowDAO followDAO;
	@Autowired
	private IndexService indexService;
	@Autowired
	private ConfigService configService;
	@Autowired
	private UserService userService;
	@Autowired
	private UserMailService userMailService;
	
	/**
	 * 关注
	 * @param target
	 * @return
	 */
	@Require
	public Result create(int target)
	{
		UserVo targetUser=userService._findVoById(target);
		if(targetUser==null)
			return ResultUtil.getFailure(Message.ERROR_DATA_ERROR);
		
		UserVo loginUser=userService.getVo(getToken());
		
		if(loginUser.getId().equals(targetUser.getId()))
			return ResultUtil.getFailure(Message.USER_FOLLOW_CREATE_FAILURE_ONESELF);
		
		if(_isFollow(loginUser.getId(), targetUser.getId()))
			return ResultUtil.getFailure(Message.USER_FOLLOW_CREATE_FAILURE_IS_EXIST);
		
		_create(loginUser,targetUser);
		userService._updateFollowCount_plus(loginUser);
		userService._updateFansCount_plus(targetUser);
		
		String mailContent=(String) configService.getValueById(Config.CONFIG_29, String.class);
		mailContent=StringUtils.replaceEach(mailContent, new String[]{"{AUTHOR}"}, new String[]{loginUser.getUsername()});
		userMailService.create(loginUser, targetUser, mailContent, mailContent , UserMailType.FOLLOW);
		
		return ResultUtil.getSuccess(Message.USER_FOLLOW_CREATE_SUCCESS);
	}
	
	/**
	 * 取消关注
	 * @param target
	 * @return
	 */
	public Result delete(int target)
	{
		UserVo targetUser=userService._findVoById(target);
		
		if(targetUser==null)
			return ResultUtil.getFailure(Message.ERROR_DATA_ERROR);
		
		UserVo loginUser=userService.getVo(getToken());
		
		if(loginUser.getId().equals(targetUser.getId()) || !_isFollow(loginUser.getId(), targetUser.getId()))
			return ResultUtil.getFailure(Message.ERROR_DATA_ERROR);
		
		_deleteBySourceAndTarget(loginUser.getId(), targetUser.getId());
		userService._updateFollowCount_minus(loginUser);
		userService._updateFansCount_minus(targetUser);
		return ResultUtil.getSuccess(Message.USER_FOLLOW_DELETE_SUCCESS);
	}
	
	/**
	 * 根据目标返回
	 * @param pn
	 * @return
	 */
	@Require
	public Pager<UserFollowVo> findVoByTarget(int pn)
	{
		return findVoByTarget(userService.getVo(getToken()).getId(),pn);
	}
	
	/**
	 * 根据源返回
	 * @param pn
	 * @return
	 */
	@Require
	public Pager<UserFollowVo> findVoBySource(int pn)
	{
		return findVoBySource(userService.getVo(getToken()).getId(),pn);
	}

	/**
	 * 根据目标返回
	 * @param pn
	 * @return
	 */
	public Pager<UserFollowVo> findVoByTarget(int target,int pn)
	{
		Pager<UserFollowVo> pager=new Pager(pn,_getCountByTarget(target),_getPageCount(),null);
		if(pager.getData_sum()>0)
			pager.setData(_findVoByTarget(target, pager.getStart(), pager.getPage_count()));
		return pager;
	}
	
	/**
	 * 根据源返回
	 * @param token
	 * @param pn
	 * @return
	 */
	public Pager<UserFollowVo> findVoBySource(int source,int pn)
	{
		Pager<UserFollowVo> pager=new Pager(pn,_getCountBySource(source),_getPageCount(),null);
		if(pager.getData_sum()>0)
			pager.setData(_findVoBySource(source, pager.getStart(), pager.getPage_count()));
		return pager;
	}
	
	/**
	 * 是否关注
	 * @param source
	 * @param target
	 * @return
	 */
	public boolean _isFollow(int source,int target)
	{
		if(source==target)
			return false;
		
		return followDAO.isFollow(source, target);
	}
	
	/**
	 * 根据目标返回
	 * @param first
	 * @param max
	 * @return
	 */
	private List<UserFollowVo> _findVoByTarget(int target,int first,int max)
	{
		return followDAO.findVoByTarget(target, first, max);
	}
	
	/**
	 * 根据源返回
	 * @param first
	 * @param max
	 * @return
	 */
	private List<UserFollowVo> _findVoBySource(int source,int first,int max)
	{
		return followDAO.findVoBySource(source, first, max);
	}
	
	/**
	 * 根据源返回数量
	 * @param source
	 * @return
	 */
	private int _getCountBySource(int source)
	{
		return followDAO.getCountBySource(source);
	}
	
	/**
	 * 根据目标返回数量
	 * @param target
	 * @return
	 */
	private int _getCountByTarget(int target)
	{
		return followDAO.getCountByTarget(target);
	}
	
	/**
	 * 创建
	 * @param follow
	 * @return
	 */
	private UserFollow _create(UserVo source,UserVo target)
	{
		UserFollow follow=new UserFollow();
		follow.setId(_getIndex());
		follow.setCreate_time(DateUtil.now());
		follow.setSource(source);
		follow.setTarget(target);
		return followDAO.create(follow);
	}
	
	/**
	 * 根据源和目标删除
	 * @param source
	 * @param target
	 * @return
	 */
	private int _deleteBySourceAndTarget(int source,int target)
	{
		return followDAO.deleteBySourceAndTarget(source, target);
	}
	
	private int _getIndex()
	{
		return indexService.getMajorById(Constants.INDEX_USER_FOLLOW);
	}
	
	private int _getPageCount()
	{
		return (Integer)configService.getValueById(Config.CONFIG_15, Integer.class);
	}
}